package JmmAndMultiThread.MultiThreads;

import java.util.Random;
import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier;

public class MultiThreadCyclicBarrier {
    public static void main(String[] args) {
//        1.先创建一个公共 CyclicBarrier 对象，设置同时等待的线程数，CyclicBarrier cyclicBarrier = new CyclicBarrier(3);
//        2.这些线程同时开始自己做准备，自身准备完毕后，需要等待别人准备完毕，这时调用 cyclicBarrier.await(); 即可开始等待别人；
//        3.当指定的同时等待的线程数都调用了 cyclicBarrier.await();时，意味着这些线程都准备完毕好，然后这些线程才同时继续执行。
        CyclicBarrier barrier=new CyclicBarrier(3);
        new Thread(()->{
            System.out.println(Thread.currentThread().getName()+" prepare for starting!");
            try {
                int index=new Random().nextInt(1000)+100;
                System.out.println(Thread.currentThread().getName()+" will prepare for "+index+" ms");
                Thread.sleep(index);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            try {
                barrier.await();
            } catch (InterruptedException e) {
                e.printStackTrace();
            } catch (BrokenBarrierException e) {
                e.printStackTrace();
            }
            System.out.println(Thread.currentThread().getName()+" is starting!");
        },"A").start();
        new Thread(()->{
            System.out.println(Thread.currentThread().getName()+" prepare for starting!");
            try {
                int index=new Random().nextInt(1000)+100;
                System.out.println(Thread.currentThread().getName()+" will prepare for "+index+" ms");
                Thread.sleep(index);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            try {
                barrier.await();
            } catch (InterruptedException e) {
                e.printStackTrace();
            } catch (BrokenBarrierException e) {
                e.printStackTrace();
            }
            System.out.println(Thread.currentThread().getName()+" is starting!");
        },"B").start();
        new Thread(()->{
            System.out.println(Thread.currentThread().getName()+" prepare for starting!");
            try {
                int index=new Random().nextInt(1000)+100;
                System.out.println(Thread.currentThread().getName()+" will prepare for "+index+" ms");
                Thread.sleep(index);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            try {
                barrier.await();
            } catch (InterruptedException e) {
                e.printStackTrace();
            } catch (BrokenBarrierException e) {
                e.printStackTrace();
            }
            System.out.println(Thread.currentThread().getName()+" is starting!");
        },"C").start();
    }
}
